`timescale 1ps/1ps
//======================================================================================================
module BF_Switch(
		In_Packet_up,		
		In_Packet_down,
		Out_Packet_up,
		Out_Packet_down
);

	parameter read_bit = 0;
	parameter D = 2;  // DataSize
   parameter offset_bits = 2;
	parameter add_offset = 2+D;
	parameter levels = 1;   
	parameter Port_Num = 2**levels;
	parameter MemoryModule_Num = Port_Num;
	parameter M = levels; //  = log( MemoryModule_Num )
   parameter Packet_Size = 2+D+M+offset_bits+M;

	input 		[Packet_Size-1:0]	 	In_Packet_up;
	input		   [Packet_Size-1:0]		In_Packet_down;
	output 		[Packet_Size-1:0]	 	Out_Packet_up;
	output		[Packet_Size-1:0]		Out_Packet_down;
	reg 		   [Packet_Size-1:0]	 	Out_Packet_up;
	reg			[Packet_Size-1:0]		Out_Packet_down;

	wire		[3:0] 			all_logic;

	assign all_logic[3] = In_Packet_up[0];
	assign all_logic[2] = In_Packet_down[0];
	assign all_logic[1] = In_Packet_up[add_offset+read_bit];   // Destination (bit) of UP port.   0-Up requested, 1-Down requested.
	assign all_logic[0] = In_Packet_down[add_offset+read_bit]; // Destination (bit) of DOWN port. 0-Up requested, 1-Down requested.
	
	always @* begin 
			//$display("sw:: %d (%b) ",all_logic, all_logic);
			case (all_logic)
				4'b0000, 4'b0001, 4'b0010, 4'b0011: begin //stop all
					Out_Packet_up = 0;
					Out_Packet_down = 0;
			   end
				4'b0100, 4'b0110: begin //down is alive and wants to go up
					Out_Packet_down = 0;
					Out_Packet_up = In_Packet_down;
			   end
				4'b0101, 4'b0111: begin //down is alive and wants to go down
					Out_Packet_up = 0;
					Out_Packet_down = In_Packet_down;
			   end
				4'b1000, 4'b1001: begin //up is alive and wants to go up
					Out_Packet_up = In_Packet_up;
					Out_Packet_down = 0;
			   end
				4'b1010, 4'b1011: begin //up is alive and wants to go down
					Out_Packet_up = 0;
					Out_Packet_down = In_Packet_up;
			   end
				4'b1100: begin //both alive, collide on up, up wins
					Out_Packet_up = In_Packet_up;
					Out_Packet_down = 0;
			   end
				4'b1101: begin //both alive, straight
					Out_Packet_up = In_Packet_up;
					Out_Packet_down = In_Packet_down;
			   end		
				4'b1110: begin //both alive, cross
					Out_Packet_up = In_Packet_down;
					Out_Packet_down = In_Packet_up; 
			   end	
				4'b1111: begin //both alive, collide on down, down wins
					Out_Packet_up = 0;
					Out_Packet_down = In_Packet_down;
			   end					
				default: begin 
					Out_Packet_down = 0;// send the Zero-Packet. 
					Out_Packet_up = 0;  // send the Zero-Packet. 
					end
			endcase 		
	end
			
	
endmodule     
//======================================================================================================
module BF_Network( 
		In_AllPackets_r,
		Out_AllPackets
	 );

	parameter levels = 1;   
	parameter D = 2;  // DataSize
   parameter offset_bits = 2;
	parameter add_offset = 0;
	parameter Port_Num = 2**levels;
	parameter MemoryModule_Num = Port_Num;
	parameter M = levels; //  = log( MemoryModule_Num )
   parameter Packet_Size = 2+D+M+offset_bits+M;

	input 	[(Packet_Size * Port_Num) - 1:0]			In_AllPackets_r;
	wire 	   [(Packet_Size * Port_Num) - 1:0]			In_AllPackets;
	output 	[(Packet_Size * MemoryModule_Num) - 1:0]	Out_AllPackets;
	
													//Levels     // Port_Num    // In-Out					 
	wire [Packet_Size - 1:0] WireMatrix [levels-1:0] [Port_Num-1:0] [1:0]; //???

	parameter i = 0;
	genvar level,port;
	
		generate
		for (port = 0; port < Port_Num; port = port+1)
		begin: x
			assign In_AllPackets[((1+port)*Packet_Size)-1:port*Packet_Size] = 
			       { port[M-1:0], In_AllPackets_r[((1+port)*Packet_Size)-1-M:port*Packet_Size]};
		end
	endgenerate 
 
   generate 
		for (level = levels-1; level >= 0; level = level-1)
		begin: a
			for (port = 0; port < Port_Num; port = port+2)
			begin: b	
				BF_Switch #(level, D, offset_bits, add_offset, levels) sw ( 
				WireMatrix[level][port+1][0], 
				WireMatrix[level][port][0], 
				WireMatrix[level][port+1][1],
				WireMatrix[level][port][1]
				);
			end
		end
	endgenerate 		

	generate
		for (port = 0; port < Port_Num; port = port+1)
		begin: c
			assign WireMatrix[levels-1][port][0] = 
			       In_AllPackets[((port+1)*Packet_Size)-1:(port*Packet_Size)];
			assign Out_AllPackets[((port+1)*Packet_Size)-1:(port*Packet_Size)] =
			       WireMatrix[0][port][1];
		end
	endgenerate

	genvar band, offset1, offset2;
	generate
		for (level = levels-1; level >= 1; level = level - 1 ) 
		begin: d
			// determine amount of Equator bands:
			// Num of Equator bands is 1 << antiLevel;
			// Size of Equator band is 1 << level;
			parameter antiLevel = levels - level -1;

			parameter AmountOfBands    = 2 ** antiLevel;
			parameter SizeOfEqBand     = 2 ** (level + 1);
			parameter SizeOfHalfEqBand = SizeOfEqBand / 2;
		
			for (band = 0; band < AmountOfBands; band = band + 1)
			begin: e
			
			   // color 0
				for (offset1 = 0; offset1 < SizeOfHalfEqBand; offset1 = offset1 + 2)
				begin: color0
					parameter beginOffset = band * SizeOfEqBand;
					// Up   - straight forward (Higher Entrance)
					assign WireMatrix[level-1][beginOffset+offset1][0] =  
					       WireMatrix[level  ][beginOffset+offset1][1];

					// Down - Cross Equator line (Higher Entrance)
					assign WireMatrix[level-1][beginOffset+offset1+SizeOfHalfEqBand][0] =  
					       WireMatrix[level  ][beginOffset+offset1+1][1];
				end

			   // color 1
				for (offset2 = 0; offset2 < SizeOfHalfEqBand; offset2 = offset2 + 2)
				begin: color1
					parameter beginOffset = band * SizeOfEqBand + SizeOfHalfEqBand;
					// Up   - Cross Equator line (Lower entrance)
					assign WireMatrix[level-1][beginOffset+offset2-SizeOfHalfEqBand+1][0] =  
					       WireMatrix[level  ][beginOffset+offset2][1];

					// Down - straight forward   (Lower entrance)
					assign WireMatrix[level-1][beginOffset+offset2+1][0] =  
					       WireMatrix[level  ][beginOffset+offset2+1][1];
				end
			end		
		end
	endgenerate
endmodule
//======================================================================================================

module MemoryModule(
		In_Packet,
		Out_Packet,
		clk );

	parameter D = 8; // Datasize
	parameter L = 8; // Log2 (Linenum)
	parameter M = 4; // Log2 (MemoryModule_num)
	parameter Line_Num = 2**L;

	//packet related info:
	parameter Packet_Size = 2+D+M+L+M;

	input [Packet_Size-1:0]	In_Packet;
	output[Packet_Size-1:0]	Out_Packet;
	
	//reg [Packet_Size-1:0]	In_Packet;
	reg[Packet_Size-1:0]	Out_Packet;
	reg [D-1:0]	MM_Data [Line_Num-1:0];

   input clk;
			
	always @ (posedge clk)
	begin a:
		if (In_Packet[0] == 0) begin
			Out_Packet <= 0;
		end
		else begin
			if (In_Packet[1] == 0) begin //Read Mode
				Out_Packet[ 1:0 ] <= In_Packet[ 1:0 ];
				Out_Packet[ D+1:2 ] <= MM_Data[ In_Packet[2+D+M+L-1:2+D+M] ];
				Out_Packet[ Packet_Size-1:2+D ] <= In_Packet[ Packet_Size-1:2+D ];
		end
			else begin // Write Mode
				//MM_Data[Intr_Add] = Data;
				//Out_P = {Pr_Add,Intr_Add,RW_flag,Data,MM_Add};
				MM_Data[ In_Packet[2+D+M+L-1:2+D+M] ] <= 
					In_Packet[ 2+D-1:2 ];
				Out_Packet <= In_Packet;
				//Out_Packet <= 2'b11;
			end
		end
	end		
endmodule
//======================================================================================================

module AllMemoryModule(
		In_AllPackets,
		Out_AllPackets,
		clk
	 );

	parameter D = 8;  // DataSize
	parameter L = 8; // offset bits
	parameter M = 2; //  = log( MemoryModule_Num )
	parameter levels = M;   

   parameter offset = 2**L;
	parameter Port_Num = 2**levels;
	parameter MemoryModule_Num = 2**M;
	
   parameter Packet_Size = 2+D+M+L+M;

	input 	[(Packet_Size * Port_Num) - 1:0]			In_AllPackets;
	input clk;
	output 	[(Packet_Size * MemoryModule_Num) - 1:0]	Out_AllPackets;

	genvar mmodule;
	generate
	for (mmodule=0; mmodule<MemoryModule_Num; mmodule = mmodule + 1)
		begin: MMs
			MemoryModule #(D,L,M) sw (
				In_AllPackets[((1+mmodule)*Packet_Size)-1:(mmodule)*Packet_Size],
				Out_AllPackets[((1+mmodule)*Packet_Size)-1:(mmodule)*Packet_Size],
				clk
			);
		end

	endgenerate 
endmodule

////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// unit tests //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////


module Test_Fullchip;

	// Packet-related information:	
	parameter read_bit = 0;
	parameter D = 4;  // DataSize
   parameter offset_bits = 4; // size of the offset (aka line num)
	parameter add_offset = 2+D; // the place in the packet where the of offset is at.
	parameter levels = 2; // (aka M)
	parameter M = levels; //  = log( MemoryModule_Num )
	parameter Port_Num = 2**levels;  // (aka memory module num)
	parameter MemoryModule_Num = Port_Num;

	// Total packet size:
   parameter Packet_Size = 2+D+M+offset_bits+M; 
	// Last (MSB) M is Return Address.

   reg clock = 0;
  	reg 	[(Packet_Size * Port_Num) - 1:0]			in;
	wire 	[(Packet_Size * MemoryModule_Num) - 1:0]	out;
	
 	wire 	[(Packet_Size * MemoryModule_Num) - 1:0]	BF1_to_Mem;
	wire 	[(Packet_Size * MemoryModule_Num) - 1:0]	Mem_to_BF2;

	// BF #1:
   BF_Network #(levels, D, offset_bits, 2+D) bfn1(in, BF1_to_Mem);  
	
	// RAM:
	AllMemoryModule #(D,offset_bits,M) mm(
			BF1_to_Mem,
			Mem_to_BF2,
			clock
	 );

	// BF #2:
    //note: we are adding_offset here - the second net should read return address rather than the main one
	 BF_Network #(levels, D, offset_bits, 2+D+M+offset_bits) bfn2 (Mem_to_BF2, out);  

   integer i,tmp1,tmp2;
	initial begin  
		
		for (i = 0; i < 4; i = i + 1 ) begin
	
			@(negedge clock) begin
			   //        RA     offset    mod    data    control
				//in = { 2'b00, 4b'0000, i[1:0], i[3:0] ,2'b11 };
				tmp1 = $random;
				tmp2 = $random;
				in = { 
					tmp1[11:0] ,2'b11, 
					tmp1[23:12] ,2'b11,
					tmp2[11:0] ,2'b11,
					tmp2[23:12] ,2'b11 };
			end
		end
		/*
		for (i = 0; i < 4; i = i + 1 ) begin
			@(negedge clock) begin
			   //        offset    mod    data    control
				//in = { 4b'0000, i[1:0], i[3:0] ,2'b11 };
				in = { 
					2'b00, 4'b0000, i[1:0], i[3:0] ,2'b01, 
					2'b00, 4'b0000, i[1:0], i[3:0] ,2'b01,
					2'b00, 4'b0000, i[1:0], i[3:0] ,2'b01,
					2'b00, 4'b0000, i[1:0], i[3:0] ,2'b01 };
			end
		end
		*/
		#6 $finish;
	end   

	always #1 clock = !clock;

	always @(in)
		begin
	  $monitor("%d(%b) TIME %d: in \t (%b|%b|%b|%b)", i[3:0],i[3:0], $time,
	  in[4*Packet_Size-1:3*Packet_Size], in[3*Packet_Size-1:2*Packet_Size],
	  in[2*Packet_Size-1:Packet_Size], in[Packet_Size-1:0] ); 
	  end
	  
	  always @(out)
		begin
	  $monitor("%d(%b) TIME %d: ==> out \t (%b|%b|%b|%b)", i[3:0],i[3:0], $time,
	  out[4*Packet_Size-1:3*Packet_Size], out[3*Packet_Size-1:2*Packet_Size],
	  out[2*Packet_Size-1:Packet_Size], out[Packet_Size-1:0] ); 	    
	  end
  
endmodule

module test_BF_network_real_2_levels_with_ruby_feed;

	// Packet-related information:	
	parameter read_bit = 0;
	parameter D = 2;  // DataSize
   parameter offset_bits = 2;
	parameter add_offset = 2+D;
	parameter levels = 4;   
	parameter Port_Num = 2**levels;
	parameter MemoryModule_Num = Port_Num;
	parameter M = levels; //  = log( MemoryModule_Num )
   parameter Packet_Size = 2+D+M+offset_bits+M; //10


  	reg 	[(Packet_Size * Port_Num) - 1:0]			in;
	wire 	[(Packet_Size * MemoryModule_Num) - 1:0]	out;
	
   BF_Network #(levels, D, offset_bits, add_offset)  m(in,out);  
 
   integer i,tmp,z;
	initial begin  
		in =  0;	
		z = 0;
		
#2 in = 224'b11110011100011111010110001111101011101111111000111001011101110011001111010100000001110010110000011100010001010111110010111101111001110110011101000001011111000111011101111001011100111100010010010111000001110101100001010011011; 
// cycle(0):	11110011100011|11101011000111|11010111011111|11000111001011|10111001100111|10101000000011|10010110000011|10001000101011|11100101111011|11001110110011|10100000101111|10001110111011|11001011100111|10001001001011|10000011101011|00001010011011|  
//         =>	00000000000000|10000011101011|11010111011111|00000000000000|11001110110011|00000000000000|00000000000000|10010110000011|11100101111011|00000000000000|00000000000000|10001001001011|00000000000000|10100000101111|00000000000000|10101000000011|
//cycle had 8 survivors, need to reschedule 8 packets new buffer size: 92 
#2 in = 224'b11111000101011111000000001011101011010001111001010011001101111101100011010010101010110011100100001100000010001111110100001100111001100010111101011001111011000111110000111000011110001100011110111011000010111011100000100101111; 
// cycle(1):	11111000101011|11100000000101|11010110100011|11001010011001|10111110110001|10100101010101|10011100100001|10000001000111|11101000011001|11001100010111|10101100111101|10001111100001|11000011110001|10001111011101|10000101110111|00000100101111|  
//         =>	11000011110001|10001111100001|00000000000000|00000000000000|10111110110001|11010110100011|00000000000000|00000000000000|00000000000000|00000000000000|10100101010101|10000001000111|10101100111101|00000000000000|11001100010111|00000000000000|
//cycle had 8 survivors, need to reschedule 8 packets new buffer size: 84 
#2 in = 224'b11110000110101111011001000011101010011010111000001110011101110110001111010010011011110010100101111100010001110111110001111001111000011100001101011011101011000001000110111001110000101100011011100011000100010010100000011010001; 
// cycle(2):	11110000110101|11101100100001|11010100110101|11000001110011|10111011000111|10100100110111|10010100101111|10001000111011|11100011110011|11000011100001|10101101110101|10000010001101|11001110000101|10001101110001|10001000100101|00000011010001|  
//         =>	11100011110011|00000000000000|00000011010001|10111011000111|00000000000000|00000000000000|00000000000000|10000010001101|10001101110001|00000000000000|00000000000000|00000000000000|00000000000000|10001000100101|00000000000000|00000000000000|
//cycle had 6 survivors, need to reschedule 10 packets new buffer size: 78 
#2 in = 224'b11111011100111111000000001011101011100100111000101100011101110011101011010101111011110010001110011100011111000111110010011010111000011010011101010011101111000011101110111001111011101100000001101111000000010000100000111100101; 
// cycle(3):	11111011100111|11100000000101|11010111001001|11000101100011|10111001110101|10101011110111|10010001110011|10001111100011|11100100110101|11000011010011|10101001110111|10000111011101|11001111011101|10000000110111|10000000100001|00000111100101|  
//         =>	00000000000000|10001111100011|00000000000000|11010111001001|00000000000000|00000000000000|00000000000000|00000000000000|10111001110101|11000101100011|00000000000000|00000000000000|11100100110101|10000000100001|00000000000000|00000000000000|
//cycle had 6 survivors, need to reschedule 10 packets new buffer size: 72 
#2 in = 224'b11110111101011111010001110111101100010100111000101111001101110000110111010011100101110010000000111100010111001011110100000000111000111011101101001001101111000101111011111000111100101100011010000011000001110100100001101110111; 
// cycle(4):	11110111101011|11101000111011|11011000101001|11000101111001|10111000011011|10100111001011|10010000000111|10001011100101|11101000000001|11000111011101|10100100110111|10001011110111|11000111100101|10001101000001|10000011101001|00001101110111|  
//         =>	10001011110111|11110111101011|00000000000000|10100111001011|00000000000000|00000000000000|00000000000000|00000000000000|11000101111001|00000000000000|00000000000000|10001101000001|10100100110111|00000000000000|10111000011011|10010000000111|
//cycle had 8 survivors, need to reschedule 8 packets new buffer size: 64 
#2 in = 224'b11111111000001111010100110011101110111001111000111011101101110100110111010110100001110010101110101100011011101011110001111101111001001000101101011011101111000111101110111001000011001100010001001111000110010000100001011000101; 
// cycle(5):	11111111000001|11101010011001|11011101110011|11000111011101|10111010011011|10101101000011|10010101110101|10001101110101|11100011111011|11001001000101|10101101110111|10001111011101|11001000011001|10001000100111|10001100100001|00001011000101|  
//         =>	00000000000000|00000000000000|00000000000000|00001011000101|00000000000000|00000000000000|10111010011011|00000000000000|11011101110011|00000000000000|00000000000000|10101101000011|00000000000000|10001100100001|00000000000000|00000000000000|
//cycle had 5 survivors, need to reschedule 11 packets new buffer size: 59 
#2 in = 224'b11111000000001111011101110111101111100000111000011010011101110000110011010100110011110010001110011100000111110111110101111010111001011100101101011001000111000001111100111001000100111100010011001011000001110000100000101010111; 
// cycle(6):	11111000000001|11101110111011|11011111000001|11000011010011|10111000011001|10101001100111|10010001110011|10000011111011|11101011110101|11001011100101|10101100100011|10000011111001|11001000100111|10001001100101|10000011100001|00000101010111|  
//         =>	11101011110101|00000000000000|00000000000000|11011111000001|11101110111011|00000000000000|00000000000000|00000000000000|10010001110011|10101001100111|00000000000000|00000000000000|00000000000000|10101100100011|00000000000000|11111000000001|
//cycle had 7 survivors, need to reschedule 9 packets new buffer size: 52 
#2 in = 224'b11110001110001111001001011111101101110010111000100101101101100110100111010101100101110011000101001100010100110011110100010101111001101110111101011101110011000010111010111001100010101100001011101111000111100001100000011100001; 
// cycle(7):	11110001110001|11100100101111|11011011100101|11000100101101|10110011010011|10101011001011|10011000101001|10001010011001|11101000101011|11001101110111|10101110111001|10000101110101|11001100010101|10000101110111|10001111000011|00000011100001|  
//         =>	00000000000000|11011011100101|10110011010011|10001111000011|10101110111001|00000000000000|10001010011001|00000000000000|11001101110111|00000000000000|00000000000000|00000000000000|00000000000000|11000100101101|00000000000000|00000000000000|
//cycle had 7 survivors, need to reschedule 9 packets new buffer size: 45 
#2 in = 224'b11110011100011111001110111011101111101110111001000101001101111100001111010010110000110011011100111100000001101111110000100010111000011101001101001011101011000111000010111001111011111100001011101111000001000111100000011111011; 
// cycle(8):	11110011100011|11100111011101|11011111011101|11001000101001|10111110000111|10100101100001|10011011100111|10000000110111|11100001000101|11000011101001|10100101110101|10001110000101|11001111011111|10000101110111|10000010001111|00000011111011|  
//         =>	00000000000000|10011011100111|11001111011111|00000000000000|00000000000000|00000000000000|00000000000000|10000010001111|10100101110101|10100101100001|00000000000000|11100001000101|00000000000000|11001000101001|00000000000000|00000000000000|
//cycle had 7 survivors, need to reschedule 9 packets new buffer size: 38 
#2 in = 224'b11111001001001111000001000111101001110000111001111011101101101100000011010101100100110011000111001100001111001111110100111011111000000000101101010000110011000000011011111001100010101100010001110111000100100010100001011001011; 
// cycle(9):	11111001001001|11100000100011|11010011100001|11001111011101|10110110000001|10101011001001|10011000111001|10000111100111|11101001110111|11000000000101|10101000011001|10000000110111|11001100010101|10001000111011|10001001000101|00001011001011|  
//         =>	00000000000000|11010011100001|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|10110110000001|00000000000000|00000000000000|00000000000000|10001001000101|10001000111011|00000000000000|00000000000000|11000000000101|
//cycle had 5 survivors, need to reschedule 11 packets new buffer size: 33 
#2 in = 224'b11110011100011111001101000011101111000011111000011111011101101010101111010011101110110011011001011100010001110011110100111011111000111100101101010000110011000110111010111001110000101100000111010011000100100100100000011111001; 
// cycle(10):	11110011100011|11100110100001|11011110000111|11000011111011|10110101010111|10100111011101|10011011001011|10001000111001|11101001110111|11000111100101|10101000011001|10001101110101|11001110000101|10000011101001|10001001001001|00000011111001|  
//         =>	00000000000000|11110011100011|10100111011101|10011011001011|00000000000000|00000000000000|00000000000000|11011110000111|11101001110111|00000000000000|10110101010111|10001001001001|10001000111001|00000000000000|00000000000000|00000000000000|
//cycle had 8 survivors, need to reschedule 8 packets new buffer size: 25 
#2 in = 224'b11110111101001111011001111111101100100011111001000101011101111011101011010011110010110011001100101100000001000111110011110011111000011111001101000001011011000000011010111001000100111100000011100011000011010000100001111011101; 
// cycle(11):	11110111101001|11101100111111|11011001000111|11001000101011|10111101110101|10100111100101|10011001100101|10000000100011|11100111100111|11000011111001|10100000101101|10000000110101|11001000100111|10000001110001|10000110100001|00001111011101|  
//         =>	00000000000000|11110111101001|00000000000000|00000000000000|00000000000000|10000110100001|00000000000000|00000000000000|10111101110101|00000000000000|00000000000000|00000000000000|11101100111111|00000000000000|00000000000000|00000000000000|
//cycle had 4 survivors, need to reschedule 12 packets new buffer size: 21 
#2 in = 224'b11111100010101111000111110011101011110010111001011001001101111110111011010100010101110010011101001100010001001111110011110011111000000100011101000111110111000000010110111000001110001100001011101111000100100011100000100101111; 
// cycle(12):	11111100010101|11100011111001|11010111100101|11001011001001|10111111011101|10101000101011|10010011101001|10001000100111|11100111100111|11000000100011|10100011111011|10000000101101|11000001110001|10000101110111|10001001000111|00000100101111|  
//         =>	11100011111001|11010111100101|10111111011101|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|10000101110111|00000000000000|00000000000000|00000000000000|00000000000000|10000000101101|00000000000000|00000000000000|
//cycle had 5 survivors, need to reschedule 11 packets new buffer size: 16 
#2 in = 224'b11111100010101111000111110111101100010011111001110000101101110001010111010101100100110010001110001100001111001111110000011010111000000110111101010011001011000010010111111000000100011100010000110011000001110100100001001000111; 
// cycle(13):	11111100010101|11100011111011|11011000100111|11001110000101|10111000101011|10101011001001|10010001110001|10000111100111|11100000110101|11000000110111|10101001100101|10000100101111|11000000100011|10001000011001|10000011101001|00001001000111|  
//         =>	11100011111011|10000111100111|00000000000000|10101011001001|00000000000000|00000000000000|00000000000000|11001110000101|10010001110001|00000000000000|00000000000000|00000000000000|11000000110111|10000100101111|10001000011001|00000000000000|
//cycle had 8 survivors, need to reschedule 8 packets new buffer size: 16 
#2 in = 224'b11110000000000111000000000001101000000000011000000000000101100000000001010000000000010010000000000100000000000001110100010101111001001100101101011000101011000100100011111000011101001100000001101011000100010011100000000100011; 
// cycle(14):	11110000000000|11100000000000|11010000000000|11000000000000|10110000000000|10100000000000|10010000000000|10000000000000|11101000101011|11001001100101|10101100010101|10001001000111|11000011101001|10000000110101|10001000100111|00000000100011|  
//         =>	00000000000000|11000011101001|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|11001001100101|00000000000000|10001001000111|10000000110101|00000000100011|00000000000000|00000000000000|
//cycle had 5 survivors, need to reschedule 11 packets new buffer size: 16 
#2 in = 224'b11110000000000111000000000001101000000000011000000000000101100000000001010000000000010011000100111100011000101011110000000000011000000000000101000000000001000000000000011001000101011100000000000001000000000000000000000000000; 
// cycle(15):	11110000000000|11100000000000|11010000000000|11000000000000|10110000000000|10100000000000|10011000100111|10001100010101|11100000000000|11000000000000|10100000000000|10000000000000|11001000101011|10000000000000|10000000000000|00000000000000|  
//         =>	00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|11001000101011|10001100010101|00000000000000|
//cycle had 2 survivors, need to reschedule 14 packets new buffer size: 16 
#2 in = 224'b11110000000000111000000000001101000000000011001000100111101100000000001010000000000010010000000000100000000000001110000000000011000000000000101000000000001000000000000011000000000000100000000000001000000000000000000000000000; 
// cycle(16):	11110000000000|11100000000000|11010000000000|11001000100111|10110000000000|10100000000000|10010000000000|10000000000000|11100000000000|11000000000000|10100000000000|10000000000000|11000000000000|10000000000000|10000000000000|00000000000000|  
//         =>	00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|00000000000000|11001000100111|00000000000000|00000000000000|
//cycle had 1 survivors, need to reschedule 15 packets new buffer size: 16 
//It took 17 cycles to read&write 50 packets on a 16 ports shared memory
		#2	$finish;
		end   

		initial  // Response
  $monitor("%b", out);  
endmodule 